﻿using System.Collections.Generic;
using ExamSharedClasses;
using ExamSharedClasses.Commands;

namespace ExamServer {

    /// <summary>
    /// (cord) ein vorgegebenes Beispiel für eine threadsichere Listenklasse, die einzelne
    /// ClientConnectionThread-Objekte enthalten kann.
    /// </summary>
    public class ClientConnectionThreadList {
        private List<ClientConnectionThread> ClientList { get; set; }
        public ClientConnectionThreadList() {
            ClientList = new List<ClientConnectionThread>();
        }

        public void Add( ClientConnectionThread h ) {
            lock ( this ) {
                ClientList.Add( h );
            }
        }

        public void Remove( ClientConnectionThread h ) {
            lock ( this ) {
                ClientList.Remove( h );
            }
        }

        public int Count() {
            lock ( this ) {
                return ClientList.Count;
            }
        }

        public ClientConnectionThread ElementAt( int i ) {
            lock ( this ) {
                return ClientList[i];
            }
        }

        public void Close() {
            lock ( this ) {
                foreach ( ClientConnectionThread cct in ClientList ) {
                    cct.Close();
                }
            }
        }

        /// <summary>
        /// Hier kann für das Durchlaufen der Liste das Objekt einfach gelockt werden
        /// damit während des Auslesens kein anderer Thread Veränderungen durchführen kann.
        /// </summary>
        public void BroadcastUserStatus() {
            lock ( this ) {
                foreach ( ClientConnectionThread clientConnection in App.ClientConnectionThreadList.ClientList ) {
                    string text = "";
                    text = clientConnection.UserAddress.ToShortInformationString();
                    if ( clientConnection.IsCurrentlyWritingAnExam )
                        text += ", schreibend";
                    App.ServerMainWindow.userList.Items.Add( text );

                    if ( clientConnection.UserAddress.UserGroup.GroupId == 2 ) {
                        // jedem Dozenten den Status der Klassenmitglieder schicken...
                        Class c = App.DatabaseConnection.GetClass( clientConnection.UserAddress );
                        ViewClass vc = new ViewClass();
                        vc.ClassWithUsers = App.DatabaseConnection.GetClassWithUsers( c.ClassId );
                        // dazu abfragen, ob sie gerade eingeloggt sind
                        foreach ( User u in vc.ClassWithUsers.UserList ) {
                            bool b1 = false, b2 = false;
                            foreach ( ClientConnectionThread cct in App.ClientConnectionThreadList.ClientList ) {
                                if ( cct.UserAddress.UserId == u.UserId ) {
                                    b1 = true;
                                    if ( cct.IsCurrentlyWritingAnExam ) {
                                        b2 = true;
                                    }
                                }
                            }
                            vc.IsUserLoggedIn.Add( b1 );
                            vc.IsUserWriting.Add( b2 );
                        }
                        clientConnection.Send( vc );

                    // Admins erhalten die Liste der angemeldeten Benutzer und deren Status
                    } else if ( clientConnection.UserAddress.UserGroup.GroupId == 4 ) {
                        ViewUsers vu = new ViewUsers();
                        User u; bool b = false;
                        foreach ( ClientConnectionThread cct in App.ClientConnectionThreadList.ClientList ) {
                            u = cct.UserAddress;
                            if ( cct.IsCurrentlyWritingAnExam )
                                b = true;
                            vu.LoggedInUserList.Add( u );
                            vu.IsUserWriting.Add( b );
                        }
                        clientConnection.Send( vu );
                    }

                }
            }
        }
    }
}
